# -*- coding: utf8 -*-
'''
Created on 2009/10/26

@author: matianyi
'''
import logging
import wsgiref.handlers
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.api import memcache
from org.andolphin import *

class RestfulMethodMiddleware(object):
    u"""RESTful中间件 """
    def __init__(self, app):  
        self.app = app  
   
    def __call__(self, environ, start_response):  
        method = webapp.Request(environ).get('_method')
        if method:
            environ['REQUEST_METHOD'] = method.upper()
            logging.getLogger().debug(u'REQUEST_METHOD: %s' % method.upper());
        return self.app(environ, start_response)  

class AuthMiddleware(object):
    u"""认证用服务"""
    
    # 不进行认证的url
    EXCLUDE_URL = ['/', '/m/login*', '/m/register*']
        
    def __init__(self, app):
        self.app = app
    
    def __call__(self, environ, start_response):
        request = webapp.Request(environ)
        if self.is_excluded(request.path):
            return self.app(environ, start_response)
        else:
            token = get_value(request.headers, 'auth_token')
            username = get_value(request.headers, 'username')
            if self.check(username, token):
                return self.app(environ, start_response)
            else:
                status = '200 OK'
                response_headers = [('Content-type','text/plain')]
                start_response(status, response_headers)
                r = Result(RESULT_AUTH_ERROR, RESULT_AUTH_ERROR_MSG,{})
                return [r.toJson()]
          
    def is_excluded(self, url):
        flag = False
        for filter in AuthMiddleware.EXCLUDE_URL:
            if(filter.endswith('*')):
                if url and url.lower().startswith(filter[0:len(filter) - 1]):
                    flag = True
            elif url and url == filter.lower():
                flag = True
            else:
                continue
        return flag
    
    def check(self, username, token):
        # 两个参数都是必需项目
        if not username or not token:
            return False
        
        cached_token = memcache.get(username, namespace='auth_token')
        # 缓存中没有
        if not cached_token:
            # 尝试从数据库中取
            user = User.gql('WHERE user_id = :1', username).get()
            # 如果数据库中已经过期或token不正确， 认证失败， 否则认证成功
            if not user or user.auth_expire < datetime.datetime.now() or user.auth_token != token:
                return False
            else:
                memcache.set(username, user.auth_token, time=1800, namespace='auth_token')
                return True
        # 如果缓存中有，但是不匹配，认证失败
        elif token != cached_token:
            memcache.delete(username, namespace='auth_token')
            return False
        # 如果缓存中有，并且匹配，认证成功。
        else:
            return True
